package com.beiming.kotlindemo

/**
 * Created by lingchen on 2020/4/30. 18:11
 * mail:lingchen52@foxmail.com
 */
class LearnLambda {

    fun main() {

        testList()
        testSet()
        testMap()
        maxLength()

    }

    private fun testList() {
        val list = ArrayList<String>()

        //listOf创建的是不可变集合，只能读取，不能添加、修改、删除
        val list1 = listOf("Apple", "Banana", "Orange", "Pear", "Grape")

        //mutableListOf创建的是可变集合
        val list2 = mutableListOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
        list.add("Apple")
        list.add("Banana")
        list.add("Orange")
        list.add("Pear")
        list.add("Grape")

        for (fruit in list1) {
            println(fruit)
        }
    }

    private fun testSet() {
        val set = setOf("Apple", "Banana", "Orange", "Pear", "Grape")

        val set1 = mutableSetOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")

        for (fruit in set) {
            println(fruit)
        }
    }

    private fun testMap() {
        val map = HashMap<String, Int>()
        map.put("Apple", 1)
        map.put("Banana", 2)
        map.put("Orange", 3)
        map.put("Pear", 4)
        map.put("Grape", 5)

        //kotlin中map的 put get使用方式
        val map1 = HashMap<String, Int>()
        //put
        map1["Apple"] = 1
        map1["Banana"] = 2
        map1["Orange"] = 3
        map1["Pear"] = 4
        map1["Grape"] = 5
        //get
        val number = map1["Apple"]

        //to不是关键字，是infix函数的相关内容
        val map2 = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
        for ((fruit, number) in map2) {
            println("fruit is $fruit, number is $number")
        }

        val map3 =
            mutableMapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
    }

    private fun maxLength() {
        val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
        var maxLengthFruit = ""
        for (fruit in list) {
            if (fruit.length > maxLengthFruit.length) {
                maxLengthFruit = fruit
            }
        }
        println("max length fruit is $maxLengthFruit")

        //函数式API
        val maxLengthFruit1 = list.maxBy { it.length }
        println("max length fruit is " + maxLengthFruit1)

        //完整lambda表达式
        val lambda = { fruit: String -> fruit.length }
        val maxLengthFruit2 = list.maxBy(lambda)

        //简化  去掉lambda量变定义
        val maxLengthFruit3 = list.maxBy({ fruit: String -> fruit.length })

        //再简化 kotlin规定，当lambda参数是函数的最后一个参数时，可以将lambda表达式移动到括号外面
        val maxLengthFruit4 = list.maxBy() { fruit: String -> fruit.length }

        //再简化 如果lambda参数是函数的唯一一个参数的话，还可以将函数的括号省略
        val maxLengthFruit5 = list.maxBy { fruit: String -> fruit.length }

        //再简化 类型推导，不必声明参数类型
        val maxLengthFruit6 = list.maxBy { fruit -> fruit.length }

        //再简化 当lambda表达式的参数列表中只有一个参数时，也不必声明参数名，可以使用it关键字来代替
        val maxLengthFruit7 = list.maxBy { it.length }

        //map函数 将集合中的每一个元素都映射成一个另外的值，映射的规则在lambda表达式中指定，最终生成一个新的集合
        //水果名变大写
        val newList = list.map { it.toUpperCase() }
        for (fruit in newList) {
            println(fruit)
        }

        //filter函数  用来过滤集合中的数据，可单独使用或配合map函数一起使用
        //保留5个字母以内的水果
        val newList2 = list.first { it.length <= 5 }
            .map { it.toUpperCase() }
        for (fruit in newList2) {
            println(fruit)
        }

        //any函数 用来判断集合中是否至少存在一个元素满足指定条件
        //all函数 用于判断集合中是否所有元素都满足指定条件
        val anyResult = list.any { it.length <= 5 }
        val allResult = list.all { it.length <= 5 }

        println("anyResult is $anyResult, allResult is $allResult")

    }

    fun javaLambda() {
        //java代码
//        new Thread(new Runnable(){
//            @Override
//            public void run(){
//                System.out.println("Thread is running")
//            }
//        }).start();
        //kotlin中创建匿名类使用object关键字
        Thread(object : Runnable {
            override fun run() {
                println("Thread is running")
            }
        }).start()

        //简化
        Thread(Runnable { println("Thread is running") }).start()

        //再简化
        Thread({ println("Thread is running") }).start()

        //再简化
        Thread { println("Thread is running") }.start()
    }
}